/*
 * A.h
 *
 *  Created on: May 22, 2011
 *      Author: federico
 */

#ifndef A_H_
#define A_H_

#include <tr1/unordered_map>
#include <string.h>
#include <iostream>
#include "../heuristics/Manhattan15Puzzle.h"
#include "../heuristics/PDBHeuristic.h"
#include "../datastructures/OpenList.h"
#include "../datastructures/FifteenPuzzleNodeA.h"
using namespace std;

#define Manhattan 0
#define PDB 1

class A {
public:
	A();
	A(Manhattan15Puzzle *manhattanCalculator);
	A(PDBHeuristic *fpdb, PDBHeuristic *spdb, PDBHeuristic *tpdb);
	virtual ~A();
	void run(FifteenPuzzleNodeA *So);

	typedef struct
	{
		long operator() (unsigned int key) const
		{
			//int c2=0x27d4eb2d; // a prime or an odd constant
			//key = (key ^ 61) ^ (key >> 16);
			//key = key + (key << 3);
			//key = key ^ (key >> 4);
			//key = key * c2;
			//key = key ^ (key >> 15);
			return key*2654435761 % 4294967296;
		}
	} HashFunction;

	typedef struct
	{
		bool operator() (const unsigned int x, const unsigned int y) const
		{
			return x == y;
		}
	} EqFuntion;

	typedef std::tr1::unordered_multimap<unsigned int, FifteenPuzzleNodeA *, HashFunction, EqFuntion> Hash;

	Hash * openclose;
	OpenList * open;
	Manhattan15Puzzle *manhattanCalculator;
	PDBHeuristic *fpdb;
	PDBHeuristic *spdb;
	PDBHeuristic *tpdb;
	int heuristic;
};

#endif /* A_H_ */
